/**
 * Definition for a binary tree node.
 * function TreeNode(val, left, right) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.left = (left===undefined ? null : left)
 *     this.right = (right===undefined ? null : right)
 * }
 */
/**
 * @param {TreeNode} root
 * @return {boolean}
 */

export var isBalanced = function (root) {
  if (!root) return true
  function getHeight(root) {
    if (!root) return 0
    return Math.max(getHeight(root.left), getHeight(root.right)) + 1
  }
  const left = getHeight(root.left)
  const right = getHeight(root.right)
  return Math.abs(left - right) <= 1 && isBalanced(root.left) && isBalanced(root.right)
}

/**
 * 优化上边方法
 * @param {*} root
 * @returns
 */
export var isBalanced2 = function (root) {
  if (!root) return true
  function getHeight(root) {
    if (!root) return [0, true]
    const [left, isLeftBalanced] = getHeight(root.left)
    const [right, isRightBalanced] = getHeight(root.right)
    const height = Math.max(left, right) + 1
    let isBalanced = isLeftBalanced && isRightBalanced
    if (Math.abs(left - right) > 1) {
      isBalanced = false
    }
    return [height, isBalanced]
  }
  return getHeight(root)[1]
}

/**
 * 再优化上边方法 (把isBalanced合并记录到height里面)
 * @param {*} root
 * @returns
 */
export var isBalanced3 = function (root) {
  if (!root) return true
  function getHeight(root) {
    if (!root) return 0
    const left = getHeight(root.left)
    const right = getHeight(root.right)
    return left === -1 || right === -1 || Math.abs(left - right) > 1
      ? -1
      : Math.max(left, right) + 1
  }
  return getHeight(root) >= 0
}
